import typeOfUtils from '../../../utils/type-of-utils'
import RenderUtils from '../RenderUtils'
import {FormItemConfig, RenderTypeItem} from "../ConfigType";
// @ts-ignore
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'; // 导入treeSelect样式
import {DynamicForm} from "../index.vue.d";
// @ts-ignore
import {CreateElement} from "vue/types/vue";
import PopupManager from "element-ui/lib/utils/popup/popup-manager";

const treeSelect: RenderTypeItem = {
  slotNames: ['after-list', 'before-list'],
  scopedSlotsNames: ['option-label', 'value-label'],
  name: 'treeSelect',
  components: {
    Treeselect
  },
  /**
   * 初始化自己的绑定值
   * @param vm
   * @param formItem
   */
  initFormValue(vm: DynamicForm, formItem: FormItemConfig) {
    if (formItem.props?.multiple) {
      vm.$set(vm.formData, formItem.prop, [])
    } else {
      vm.$set(vm.formData, formItem.prop, undefined)
    }
  },
  /**
   * @param vm
   * @param formItem
   */
  initFormItem(vm: DynamicForm, formItem: FormItemConfig) {
    // @ts-ignore
    if (typeOfUtils.isEmpty(formItem.props.options)) {
      vm.$set(formItem.props, 'options', [])
    }
    // @ts-ignore
    if (typeOfUtils.isFunction(formItem.props.asyncSetOptions)) {
      vm.$set(formItem.props, 'loading', true)
      // @ts-ignore
      formItem.props.asyncSetOptions().then(res => {
        vm.$set(formItem.props, 'options', res)
      }).finally(() => {
        // @ts-ignore
        formItem.props.loading = false
      })
    }
  },
  /**
   * 异步加载
   * @param formItem
   * @param vm
   * @param query
   */
  asyncSetOptions(formItem: FormItemConfig, vm: DynamicForm, query) {
    // @ts-ignore
    if (typeOfUtils.isFunction(formItem.props.asyncSetOptions)) {
      // @ts-ignore
      formItem.props.loading = true
      // @ts-ignore
      formItem.props.asyncSetOptions(query).then(res => {
        vm.$set(formItem.props, 'options', res)
      }).finally(() => {
        // @ts-ignore
        formItem.props.loading = false
      })
    }
  },
  /**
   *
   * @param createElement
   * @param vm
   * @param formItem
   * @return {VNode[]}
   */
  render(createElement: CreateElement, vm: DynamicForm, formItem: FormItemConfig) {
    let tag = 'Treeselect'
    const options = RenderUtils.getItemPropsOptions(formItem)
    const props = {
      label: formItem.props?.props?.label || 'label',
      value: formItem.props?.props?.value || 'value',
      children: formItem.props?.props?.children || 'children',
    }
    if (formItem.props?.appendToBody !== false) {
      if (formItem.props) {
        vm.$set(formItem.props, 'appendToBody', true)
      } else {
        vm.$set(formItem, 'props', {
          appendToBody: true,
        })
      }
    }
    const config = RenderUtils.getConfig(vm, formItem, {
      staticClass: 'vueTreeSelectMini vueTreeSelectSmall',
      props: {
        placeholder: '请选择',
        options,
        normalizer: (node) => {
          if (formItem.props?.normalizer) {
            return formItem.props.normalizer(node)
          }
          if (!formItem.props?.loadOptions) {
            if (typeOfUtils.isEmpty(node[props.children])) {
              return {
                id: node[props.value],
                label: node[props.label],
                children: undefined
              }
            }
          }
          return {
            id: node[props.value],
            label: node[props.label],
            children: node[props.children],
          }
        },
        noChildrenText: formItem.props?.noChildrenText || '暂无子节点',
        noOptionsText: formItem.props?.noOptionsText || '没有可用选项',
        noResultsText: formItem.props?.noResultsText || '未匹配到结果',
        valueConsistsOf: formItem.props?.valueConsistsOf || 'ALL', // 默认选中所有
      },
      on: {
        input: (val) => {
          if (typeOfUtils.isFunction(formItem.events?.input)) {
            // @ts-ignore
            formItem.events.input(options, val)
          }
          vm.$emit('selectChange', formItem.prop, vm.formData, {type: this.name, options})
        },
        open: (e) => {
          if (formItem.props?.appendToBody !== false) {
            vm.$set(formItem.props, 'zIndex', PopupManager.nextZIndex())
          }
          if (typeOfUtils.isFunction(formItem.events?.focus)) {
            // @ts-ignore
            formItem.events.open(options, e)
          }
          // @ts-ignore
          if (typeOfUtils.isFunction(formItem.props.focusLoadAgain)) {
            // @ts-ignore
            if (formItem.props.focusLoadAgain()) {
              this.asyncSetOptions(formItem, vm)
            }
          }
        }
      },
      directives: [
        {
          name: 'loading',
          value: formItem.props?.loading || false
        }
      ],
    }, this)
    config.scopedSlots = RenderUtils.renderScopedSlots(formItem, createElement, this.scopedSlotsNames, vm)
    const children = RenderUtils.renderSlotsChildren(formItem, createElement, this.slotNames, vm)
    return [
      createElement(tag, config, children)
    ]
  }
}

export default treeSelect
